package com.sales.service.impl;

import com.sales.dao.ProfileDao;
import com.sales.entity.Account;
import com.sales.entity.Profile;
import com.sales.enums.ExceptionEnum;
import com.sales.enums.UserTypeEnums;
import com.sales.excption.SalesException;
import com.sales.service.AccountService;
import com.sales.service.ProfileService;
import com.sales.signUpReq.ProfileSignUpReq;
import com.sales.util.UuidUtil;
import com.sales.vo.ProfileVo;
import com.sales.vo.ReferralCodesVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.awt.color.ProfileDataException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by lihu on 2017/9/7.
 */
@Service
public class ProfileServiceImpl implements ProfileService {

    @Autowired
    ProfileDao profileDao;

    @Autowired
    AccountService accountService;

    @Override
    @Transactional
    public void putProfile(ProfileSignUpReq profileSignUpReq) {
        Profile profile = profileDao.findByUsername(profileSignUpReq.getUsername());
        //校验账号是否存在
        if (profile == null) {
            throw new SalesException(ExceptionEnum.PROFILE_NOT_EXISTS);
        }
        BeanUtils.copyProperties(profileSignUpReq, profile);
        profileDao.save(profile);
    }

    @Override
    public ProfileVo getProfile(String username) {
        Profile profile = profileDao.findByUsername(username);
        //校验账号是否存在
        if (profile == null) {
            throw new SalesException(ExceptionEnum.PROFILE_NOT_EXISTS);
        }
        ProfileVo profileVo = new ProfileVo();
        BeanUtils.copyProperties(profile, profileVo);

        Account account = accountService.getAccount(username);
        profileVo.setAmount(account.getSurplusAmount() / 100d);
        profileVo.setMobile(username);
        profileVo.setUserType(profile.getUserTypeEnums().toString());
        profileVo.setCount(profile.getCount());
        return profileVo;
    }

    @Override
    public ReferralCodesVo getReferralCodes(String username, Pageable pageable) {
        Profile profile = profileDao.findByUsername(username);
        //校验账号是否存在
        if (profile == null) {
            throw new SalesException(ExceptionEnum.PROFILE_NOT_EXISTS);
        }

        //获取上级账号信息
        Profile parentProfile = null;
        if (!profile.getUserTypeEnums().equals(UserTypeEnums.ZERO)) {
            parentProfile = profileDao.findByUsername(profile.getParentUserName());
        }
        String rootCode = "";
        //校验账号是否存在
        if (parentProfile != null) {
            rootCode = parentProfile.getReferralCode();
        }
        ReferralCodesVo referralCodesVo = new ReferralCodesVo(rootCode, profile.getReferralCode());
        //不是最下级 获取下级邀请码信息
        if (profile.getUserTypeEnums() != UserTypeEnums.TWO) {
            getCodeInfoList(referralCodesVo, username, pageable);
        }
        return referralCodesVo;
    }

    /**
     * 减少推荐码次数
     *
     * @param code
     */
    @Override
    @Transactional
    public void reduceRefCode(String code) {
        Profile profile = profileDao.findByReferralCode(code);
        if (profile.getCount() > 0) {
            profile.setCount(profile.getCount() - 1);
            profileDao.save(profile);
        } else {
            throw new SalesException(ExceptionEnum.USER_PROFILE_NOT_COUNT);
        }

    }

    @Override
    public List<String> getReferralCodes(String username) {
        List<String> codes = new ArrayList<>();
        Profile profile = profileDao.findByUsername(username);
        //校验账号是否存在
        if (profile == null) {
            throw new SalesException(ExceptionEnum.PROFILE_NOT_EXISTS);
        }
        codes.add(profile.getReferralCode());
        //不是最下级 获取下级邀请码信息
        if (profile.getUserTypeEnums() != UserTypeEnums.TWO) {
            profileDao.findListByParentUserName(profile.getUsername()).forEach(e ->
                    codes.add(e.getReferralCode())
            );
        }
        return codes;
    }

    @Override
    public void createProfile(String mobile, String username) {
        Profile profile = profileDao.findByUsername(username);
        //校验账号信息 并判断级别
        if (profile == null) {
            throw new SalesException(ExceptionEnum.PROFILE_NOT_EXISTS);
        }
        if (profile.getUserTypeEnums() == UserTypeEnums.TWO) {
            throw new SalesException(ExceptionEnum.PERMISSION_DENIED);
        }
        Profile profileNew = profileDao.findByUsername(mobile);
        if (profileNew != null) {
            throw new SalesException(ExceptionEnum.PROFILE_EXISTS);
        }
        profileNew = new Profile(UuidUtil.getUuid(), getReferralCode());
        profileNew.setParentUserName(username);
        profileNew.setUsername(mobile);
        //判断生产账号类型
        profileNew.setUserTypeEnums(profile.getUserTypeEnums() == UserTypeEnums.ONE ?
                UserTypeEnums.TWO : UserTypeEnums.ONE);
        profile.setCodeCount(profile.getCodeCount() + 1);

        //生成账号信息
        accountService.createAccount(mobile);
        profileDao.save(profile);
        profileDao.save(profileNew);
    }

    @Override
    public Profile getProfileWithCode(String username, String code) {
        return profileDao.findByParentUserNameAndReferralCode(username, code);
    }

    @Override
    @Transactional
    public void checkCode(String code) {
        Profile profile = profileDao.findByReferralCode(code);
        if (profile == null) {
            throw new SalesException(ExceptionEnum.PROFILE_NOT_EXISTS);
        }
        if (!profile.isEnabled()) {
            throw new SalesException(ExceptionEnum.CODE_OVERDUE);
        }
        if (profile.getCount() <= 0) {
            throw new SalesException(ExceptionEnum.USER_PROFILE_NOT_COUNT);
        }
    }


    //生产随机邀请码
    private String getReferralCode() {
        String code = "hxbs";
        Random random = new Random();
        Integer number = random.nextInt(999999);
        code += number;
        Profile profile = profileDao.findByReferralCode(code);
        if (profile != null) {
            code = getReferralCode();
        }
        return code;
    }


    //获取子账号信息
    private void getCodeInfoList(ReferralCodesVo referralCodesVo, String username, Pageable pageable) {
        Page<Profile> profiles = profileDao.findListByParentUserNameOrderByAddTimeDesc(username, pageable);
        List<ReferralCodesVo.CodeInfo> list = profiles.getContent().stream().map(e ->
                new ReferralCodesVo.CodeInfo(e.getReferralCode(), e.getUsername(),
                        e.isEnabled() ? "已启用" : "已禁用", e.getName(), e.getCount())
        ).collect(Collectors.toList());
        referralCodesVo.setTotalPages(profiles.getTotalPages());
        referralCodesVo.setTotalElements(profiles.getTotalElements());
        referralCodesVo.setMyList(list);

    }

    @Override
    @Transactional
    public void updateStatus(String code, boolean enabled) {
        Profile p = profileDao.findByReferralCode(code);
        p.setEnabled(enabled);
    }

    @Override
    public Map<String, String> getNameWithCode(Set<String> codes) {
        Map<String, String> map = new HashMap<>();
        if (codes.size() > 0) {
            List<Profile> profiles = profileDao.findListByReferralCodeIn(codes);
            profiles.forEach(e ->
                    map.put(e.getReferralCode(), e.getName())
            );
        }
        return map;
    }

    @Override
    public void updateRefCode(String code, int count, String userName) throws SalesException {
        //找父类账号
        Profile judgeProfile = profileDao.findByUsername(userName);
        //找推荐码账号
        Profile profile = profileDao.findByReferralCode(code);
        //判断父类推荐码的权限
        if (judgeProfile != null && judgeProfile.getUserTypeEnums().equals(UserTypeEnums.ZERO)) {
            if (profile != null) {
                profile.setCount(profile.getCount()+count);
                profileDao.save(profile);
                return;
            }
        } else if (judgeProfile != null && judgeProfile.getUserTypeEnums().equals(UserTypeEnums.ONE)) {
            if (judgeProfile.getCount() - count >= 0) {
                profile.setCount(profile.getCount()+count);
                judgeProfile.setCount(judgeProfile.getCount() - count);
                profileDao.save(profile);
                profileDao.save(judgeProfile);
                return;
            } else {
                throw new SalesException(ExceptionEnum.USER_PROFILE_NOT_COUNT);
            }
        } else if (judgeProfile.getUserTypeEnums().equals(UserTypeEnums.TWO)) {
            throw new SalesException(ExceptionEnum.PERMISSION_DENIED);
        }
    }

}
